package Controllers;

import Configs.Config;
import GUIs.f_nhanvien_chunhatro_qlgiaphong;
import com.db4o.ObjectSet;
import com.db4o.ext.DatabaseClosedException;
import com.db4o.ext.DatabaseReadOnlyException;
import com.db4o.ext.Db4oIOException;
import com.db4o.query.Predicate;
import com.db4o.query.Query;
import java.awt.HeadlessException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import models.ChiTietGia;
import models.GiaPhong;
import models.LoaiPhong;

public class GiaPhongController {

    private final Config conn;
    private BieuThucChinhQuy btcq;

    public GiaPhongController(Config conn) {
        this.conn = conn;
    }

    public int generateIDGiaPhong() {
        Query query = this.conn.getConn().query();
        query.constrain(GiaPhong.class);
        query.sortBy((GiaPhong giaPhongA, GiaPhong giaPhongB) -> giaPhongB.getMagia() - giaPhongA.getMagia());
        try {
            GiaPhong giaPhong = (GiaPhong) query.execute().next();
            int maxIDGiaPhong = giaPhong.getMagia() + 1;
            return maxIDGiaPhong;
        } catch (Exception ex) {
            return 1;
        }
    }

    public String giaPhong(Set<ChiTietGia> chiTietGias) throws ParseException {
        Set<ChiTietGia> chiTietGiaTemp = new HashSet<ChiTietGia>();

        Date today = Calendar.getInstance().getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
        for (ChiTietGia chiTietGia : chiTietGias) {
            //    System.out.println(sdf.parse(sdf.format(chiTietGia.getThoidiemapdung())));
            if (DateNTime.compareDate(sdf.parse(sdf.format(today)), sdf.parse(sdf.format(chiTietGia.getThoidiemapdung()))) != 1) {
                chiTietGiaTemp.add(chiTietGia);
            }
        }
        ChiTietGia chiTietGiaSD = null;
        int i = 0;
        for (ChiTietGia chiTietGia : chiTietGiaTemp) {
            if (i == 0) {
                chiTietGiaSD = chiTietGia; // gia tri dau tien la max
                i++;
            }
            if (DateNTime.compareDate(sdf.parse(sdf.format(chiTietGiaSD.getThoidiemapdung())), sdf.parse(sdf.format(chiTietGia.getThoidiemapdung()))) == 1) {
                chiTietGiaSD = chiTietGia;
            }
        }
        return chiTietGiaSD.getGiaphong().getGia() + "";
    }

    public void Show() {

    }

    public boolean Add(f_nhanvien_chunhatro_qlgiaphong them_giaphong) {
        int idgiaphong = Integer.parseInt(them_giaphong.tfidgiaphong.getText());
        try {
            final long gia = Long.parseLong(XuLyCurrency.remove(them_giaphong.tfgiaphong.getText()));
            String loaiPhong = them_giaphong.cbbloaiphong.getSelectedItem().toString();
            if (loaiPhong.equals("- Chọn loại phòng -")) {
                JOptionPane.showMessageDialog(them_giaphong, "Bạn chưa chọn loại phòng", "Thông báo", JOptionPane.ERROR_MESSAGE);
                them_giaphong.cbbloaiphong.requestFocus();
            } else {
                Date ngayApDung = them_giaphong.dpngayapdung.getDate();
                ObjectSet<GiaPhong> giaPhongs = this.conn.getConn().query(new Predicate<GiaPhong>() {
                    @Override
                    public boolean match(GiaPhong et) {
                        return et.getGia() == gia;
                    }
                });
                LoaiPhong loaiPhongRef = this.conn.getConn().query(new Predicate<LoaiPhong>() {
                    @Override
                    public boolean match(LoaiPhong et) {
                        return et.getMotaloai().equals(loaiPhong);
                    }
                }).next();
                if (giaPhongs.size() == 0) {
                    GiaPhong giaPhongThem = new GiaPhong(idgiaphong, gia);

                    ChiTietGia chiTietGiaThem = new ChiTietGia();
                    chiTietGiaThem.setThoidiemapdung(ngayApDung);
                    chiTietGiaThem.setGiaphong(giaPhongThem);
                    chiTietGiaThem.setNhatro(them_giaphong.nhaTroThem);
                    chiTietGiaThem.setLoaiphong(loaiPhongRef);

                    them_giaphong.nhaTroThem.addChiTietGia(chiTietGiaThem);
                    loaiPhongRef.addChiTietGia(chiTietGiaThem);
                    giaPhongThem.addChiTietGia(chiTietGiaThem);

                    this.conn.getConn().store(chiTietGiaThem);
                    this.conn.getConn().store(giaPhongThem);

                } else {
                    ChiTietGia chiTietGiaThem = new ChiTietGia();
                    chiTietGiaThem.setThoidiemapdung(ngayApDung);
                    chiTietGiaThem.setGiaphong(giaPhongs.next());
                    chiTietGiaThem.setNhatro(them_giaphong.nhaTroThem);
                    chiTietGiaThem.setLoaiphong(loaiPhongRef);

                    them_giaphong.nhaTroThem.addChiTietGia(chiTietGiaThem);
                    loaiPhongRef.addChiTietGia(chiTietGiaThem);

                    this.conn.getConn().store(chiTietGiaThem);
                }
                return true;
            }
        } catch (NumberFormatException | HeadlessException | Db4oIOException | DatabaseClosedException | DatabaseReadOnlyException ex) {
            JOptionPane.showMessageDialog(them_giaphong, "Giá phòng không hợp lệ.", "Thông báo", JOptionPane.ERROR_MESSAGE);
            them_giaphong.tfgiaphong.requestFocus();
        }
        return false;
    }

    public boolean Edit(f_nhanvien_chunhatro_qlgiaphong sua_giaphong) {
        final int idgiaphong = Integer.parseInt(sua_giaphong.tfidgiaphong.getText());
        try {
            final long giaSua = Long.parseLong(XuLyCurrency.remove(sua_giaphong.tfgiaphong.getText()));
            String loaiPhongSua = sua_giaphong.cbbloaiphong.getSelectedItem().toString();
            if (loaiPhongSua.equals("- Chọn loại phòng -")) {
                JOptionPane.showMessageDialog(sua_giaphong, "Bạn chưa chọn loại phòng", "Thông báo", JOptionPane.ERROR_MESSAGE);
                sua_giaphong.cbbloaiphong.requestFocus();
            } else {
                Date ngayApDungSua = sua_giaphong.dpngayapdung.getDate();
                ObjectSet<GiaPhong> giaPhongs = this.conn.getConn().query(new Predicate<GiaPhong>() {
                    @Override
                    public boolean match(GiaPhong et) {
                        return et.getMagia() != idgiaphong
                                && et.getGia() == giaSua;
                    }
                });

                LoaiPhong loaiPhongRef = this.conn.getConn().query(new Predicate<LoaiPhong>() {
                    @Override
                    public boolean match(LoaiPhong et) {
                        return et.getMotaloai().equals(loaiPhongSua);
                    }
                }).next();

                LoaiPhong loaiPhongOld = this.conn.getConn().query(new Predicate<LoaiPhong>() {
                    @Override
                    public boolean match(LoaiPhong et) {
                        return et.getMotaloai().equals(sua_giaphong.loaiPhongOld);
                    }
                }).next();

                ChiTietGia chiTietGiaSua = this.conn.getConn().query(new Predicate<ChiTietGia>() {
                    @Override
                    public boolean match(ChiTietGia et) {
                        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
                        try {
                            return DateNTime.compareDate(sdf.parse(sdf.format(et.getThoidiemapdung())), sdf.parse(sua_giaphong.ngayApDungOld)) == 0
                                    && et.getGiaphong().getMagia() == idgiaphong
                                    && et.getLoaiphong().getMotaloai().equals(sua_giaphong.loaiPhongOld)
                                    && et.getNhatro().getGPKD().equals(sua_giaphong.nhaTroThem.getGPKD());
                        } catch (ParseException ex) {
                            Logger.getLogger(GiaPhongController.class.getName()).log(Level.SEVERE, null, ex);
                        }
                        return false;
                    }
                }).next();

                loaiPhongOld.removeChiTietGia(chiTietGiaSua);

                if (giaPhongs.size() == 0) {
                    GiaPhong giaPhongSua = this.conn.getConn().query(new Predicate<GiaPhong>() {
                        @Override
                        public boolean match(GiaPhong et) {
                            return et.getMagia() == idgiaphong;
                        }
                    }).next();

                    giaPhongSua.setGia(giaSua);

                    this.conn.getConn().store(giaPhongSua);

                } else {
                    GiaPhong giaPhongCu = chiTietGiaSua.getGiaphong();
                    giaPhongCu.removeChiTietGia(chiTietGiaSua);
                    if (giaPhongCu.getDschitietgia().isEmpty()) {
                        this.conn.getConn().delete(giaPhongCu);
                    }
                    GiaPhong giaPhongMoi = giaPhongs.next();
                    chiTietGiaSua.setGiaphong(giaPhongMoi);
                    giaPhongMoi.addChiTietGia(chiTietGiaSua);
                }
                chiTietGiaSua.setThoidiemapdung(ngayApDungSua);
                chiTietGiaSua.setLoaiphong(loaiPhongRef);
                loaiPhongRef.addChiTietGia(chiTietGiaSua);
                this.conn.getConn().store(chiTietGiaSua);
                this.conn.getConn().store(loaiPhongOld);
                return true;
            }
        } catch (NumberFormatException | HeadlessException | Db4oIOException | DatabaseClosedException | DatabaseReadOnlyException ex) {
            JOptionPane.showMessageDialog(sua_giaphong, "Giá phòng không hợp lệ.", "Thông báo", JOptionPane.ERROR_MESSAGE);
            sua_giaphong.tfgiaphong.requestFocus();
        }
        return false;
    }

    public boolean Delete(int idGiaPhong) {
        try {
            ObjectSet<GiaPhong> xoa = this.conn.getConn().query(new Predicate<GiaPhong>() {
                @Override
                public boolean match(GiaPhong et) {
                    return et.getMagia() == idGiaPhong;
                }
            });
            while (xoa.hasNext()) {
                GiaPhong giaPhong = xoa.next();
                if (giaPhong.getDschitietgia().isEmpty()) {
                    this.conn.getConn().delete(giaPhong);
                } else {
                    return false;
                }
            }
            return true;
        } catch (Db4oIOException | DatabaseClosedException | DatabaseReadOnlyException | HeadlessException ex) {
            return false;
        }
    }
}
